package app.service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import app.entity.MeterDataBean;
import app.entity.MeterExcelData;
import siotwx.dao.MeterDao;
import siotwx.dao.ReadmeterDao;
import siotwx.dao.SQLServerDao;
import siotwx.entity.Readmeter;
/**
 * 这是一个用来处理电表的相关操作的逻辑层类
 * 
 * @author 周超 2018年3月7日 
 *
 */
@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
@Service("ReadMeterService")
public class ReadMeterService {
	@Autowired
	@Qualifier("ReadmeterDao")
	private ReadmeterDao readmeterDao;
	
	private static final Log logger = LogFactory.getLog(ReadMeterService.class);

	private static final String DBMeterKID = null;

	//获取电表数量
	/**
	 * 该方法用来获取当前的电表数量
	 * @author 周超 2018年3月6日 
	 * 
	 * @return 电表总数量
	 */
	@Transactional(readOnly=true)
	public Integer getCount(){
		Integer count = readmeterDao.count(null);
		return count;
	}
	
	//获取电表的全部条目
	/**
	 * 用于获取当前系统中的全部电表信息条目
	 * @author 周超 2018年3月6日
	 * 
	 * @return 电表的全部数目
	 */
	@Transactional(readOnly=true)
	public List<Readmeter> getList(){
		List<Readmeter> ReadMeterList = readmeterDao.getlist(null);
		return ReadMeterList;
	}
	
	//获取指定的电表信息
	/**
	 * 用来获取指定电表的信息（主要就是在缓存表中的当前读数与安装地址之类的信息）
	 * @author 周超 2018年3月6日 
	 * 
	 * @param DBMeterKID 指定电表的ID
	 * @return 指定电表的使用缓存表信息
	 */
	@Transactional(readOnly=true)
	public Readmeter get(String DBMeterKID){
		return readmeterDao.get(DBMeterKID);
	}
	
	//更新新的电表条目，该方法在使用的时候如果存在则更新，如果不存在则进行添加
	/**
	 * 更新电表的条目，当数据库中已经存在时进行更新当数据库中不存在时进行添加
	 * @author 周超 2018年3月6日 
	 * 
	 * @param readmeters 要更新的电表集合list
	 * @return 返回受影响的数据库条目数
	 */
	@Transactional(readOnly=false)
	private Integer insertOrUpdate(List<Readmeter> readmeters){
		int flag=0;
		if (readmeters!=null&& readmeters.size()!=0) {
			for(Readmeter readmeter:readmeters){
				Integer inserted = readmeterDao.insert(readmeter);
				if (inserted==2) {
					flag+=inserted/2;
				}else if (inserted==1) {
					flag+=inserted;
				}
			}
		}
		return flag;
	}
	
	//获取当前系统中存在的电表的最新读数信息(该方法读取的数据库与上面的方法中读取的信息不在同一个数据库中
	//该要获取的信息在另一台服务器的sqlserver数据库中)
	//由于该方法使用的数据操作不在同一个数据库中，不能使用当前数据源的事务
	/**
	 * 用于获取当前系统中已经存在的电表的最新的读表数据
	 * @author 周超 2018年3月6日
	 * 
	 * @return 返回系统中已经存在的电表的最新的读表数据
	 */
	@Transactional(readOnly=true)
	public List<Readmeter> getMeterData(){
		return MeterDao.getMeterData();
	}
	//获取当前系统中存在的电表的最新读数信息(该方法读取的数据库与上面的方法中读取的信息不在同一个数据库中
	//该要获取的信息在另一台服务器的sqlserver数据库中)
	//由于该方法使用的数据操作不在同一个数据库中，不能使用当前数据源的事务
	/**
	 * 用于获取当前系统中已经存在的电表的最新的读表数据
	 * @author 周超 2018年3月6日
	 * 
	 * @return 返回系统中已经存在的电表的最新的读表数据
	 */
	@Transactional(readOnly=true)
	public List<Readmeter> getMeterData(int pageNum,int pageSize){
		List<Readmeter> meterData = readmeterDao.getlist(null);
		List<Readmeter> res=new ArrayList<>();
		int flag=meterData.size()<=pageNum*pageSize?meterData.size():pageNum*pageSize;
		for(int index=(pageNum-1)*pageSize;index<flag;index++){
			res.add(meterData.get(index));
		}
		return res;
	}
	
	//用于执行更新当前数据库中的已经存在的电表的最新读数信息
	/**
	 * 用于执行更新当前数据库中的已经存在的电表的最新读数信息
	 * @author 周超 2018年3月6日
	 * 
	 * @return 返回受影响的行数
	 */
	@Transactional(readOnly=false)
	public Integer executMeterUpdate(){
		return insertOrUpdate(getMeterData());
	}
	
	//获取指定电表的月用电量数据折现
	/**
	 * 该方法用来获取指定电表的六个月的数据
	 * @author 周超 2018年3月7日
	 * 
	 * @param DBMeterKID 电表标识符
	 * @return
	 */
	@Transactional(readOnly=true)
	public MeterDataBean getMeterTendendyM(String DBMeterKID){
		return MeterDao.getMeterTendencyM(DBMeterKID);
	}
	/**
	 * 该方法用来获取指定电表的30天的数据
	 * @author 周超 2018年3月7日
	 * 
	 * @param DBMeterKID 电表标识符
	 * @return
	 */
	@Transactional(readOnly=true)
	public MeterDataBean getMeterTendendyD(String DBMeterKID){
		return MeterDao.getMeterTendencyD(DBMeterKID);
	}
	
	//获取各个电表的上月电表用电量
	@Transactional(readOnly=true)
	public List<MeterExcelData> getLastMonthData(){

		String kid="";
		List<MeterExcelData> res=new ArrayList<>();
		//获取所有的电表编号
		
		String sqlMeter="select HD_Meter.ID KID,HD_Meter.[No] KNum,HD_Meter.ColectorNo DBCollectorNum,HD_Meter.Location KLocation from HD_Meter";
		List<HashMap<String,String>> meters = SQLServerDao.executeSqlWithResult(sqlMeter);
		for(int i=0;i<meters.size();i++){
			kid=meters.get(i).get("KID");
			meterNum(kid, res);
		}
		return res;
	}

	public static void main(String[] args) {
		new ReadMeterService().meterNum("", null);
	}
	
	public void meterNum(String kid, List<MeterExcelData> res) {
		//获取月
		//获取月
		String dateFrom = "";
		Date date = new Date();
		date.setMonth(date.getMonth()-1);
		Calendar time = Calendar.getInstance();
		time.setTime(date);
		//time.set(Calendar.MONTH, time.get(Calendar.MONTH)-1);
		dateFrom+=time.get(Calendar.YEAR)+"-";
		dateFrom+=(time.get(Calendar.MONTH)+1)+"-";
		dateFrom+="1";
		//获取本月的上一月最后一天
		String dateTo="";
		time.setTime(new Date());
		dateTo+=time.get(Calendar.YEAR)+"-";
		dateTo+=(time.get(Calendar.MONTH)+1)+"-";
		dateTo+=1;
		//获取该电表信息
		String sql="SELECT "
				+ "HD_ReadMeter.MeterID  DBMeterKID, "
				+ "HD_Meter.ColectorNo DBCollectorNum, "
				+ "HD_Meter.Location KLocation, "
				+ "HD_ReadMeter.MeterNo KNum, "
				+ "HD_ReadMeter.ThisRead KThisTimeRead, "
				+ "HD_ReadMeter.LastRead KLastTimeRead, "
				+ "HD_ReadMeter.ReadTime KReadTime "
				+ "FROM  "
				+ "HD_ReadMeter LEFT JOIN HD_Meter ON HD_ReadMeter.MeterID=HD_Meter.ID"
				+ " WHERE HD_ReadMeter.MeterID='"+kid+"' "
				+ "AND HD_ReadMeter.ReadTime>'"+dateFrom+"' "
				+ "AND HD_ReadMeter.ReadTime<'"+dateTo+"' "
				+ "order by HD_ReadMeter.ReadTime desc";
		List<HashMap<String,String>> result = SQLServerDao.executeSqlWithResult(sql);
		int size = result.size();
		if (result!=null&&size>0) {
			HashMap<String, String> first = result.get(0);
			String KThisTimeRead = first.get("KThisTimeRead");
			HashMap<String, String> last = result.get(size - 1);
			String KLastTimeRead = last.get("KLastTimeRead");
			BigDecimal f = new BigDecimal(KThisTimeRead);
			BigDecimal t = new BigDecimal(KLastTimeRead);
			BigDecimal r = f.subtract(t);
			MeterExcelData dataBean = new MeterExcelData();
			dataBean.setMeters(r.floatValue() + "");
			dataBean.setMouths(dateFrom.substring(0, dateFrom.lastIndexOf("-")));
			dataBean.setDb(first.get("KNum"));
			dataBean.setAddress(first.get("KLocation"));
			dataBean.setMeter(meterNum(kid));
			res.add(dataBean);
		}
	}
	//获取指定电表的当前读数
	private String meterNum(String kid) {
		String sql="SELECT TOP 1 ThisRead FROM "
				+ "HD_ReadMeter WHERE MeterID='"+kid+"' "
				+ "ORDER BY ThisRead DESC";
		List<HashMap<String,String>> result = SQLServerDao.executeSqlWithResult(sql);
		if (result!=null&&!result.isEmpty()) {
			return result.get(0).get("ThisRead");
		}
		return "-----";
	}
	
	
	//获取每天的电表用电量
	/**
	 * 该方法用来获取全部电表在指定天数内每一天的耗电量
	 * @author 周超 2018年3月7日
	 * 
	 * @param days 要获取的天数
	 * @return
	 */
	public List<List<String>> getMeterNumPreDay(int days){

		
		//根据当前时间往前推算
		long timeNow = System.currentTimeMillis();
		
		long timeOne = timeNow-(3600*24*days*1000L);
		
		Date date = new Date(timeOne);
		
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		
		String timeStr = sdf.format(date);
		
		//获取前n天所有电表的用电量数据
		String sql ="SELECT ThisUse,ReadTime FROM HD_ReadMeter WHERE ReadTime> '"+timeStr+"' ORDER BY ReadTime DESC";
		
		List<HashMap<String, String>> list = SQLServerDao.executeSqlWithResult(sql);
		
		//建立一个string类型的数据用于存放时间和用电量数据
		List<List<String>> res = new ArrayList<>();
		List<String> times = new ArrayList<>();
		List<String> meterNum = new ArrayList<>();
		
		if (list!=null&&list.size()>0) {
			//根据数据统计日耗电总量
			//保存第一条记录里的时间
			String tempTimeStr = list.get(0).get("ReadTime").substring(0,10);
			
			BigDecimal dayUse=new BigDecimal("0.00"); 
			
			for (HashMap<String, String> dataMap : list) {
				String time = dataMap.get("ReadTime").substring(0, 10);
				
				if (time.equals(tempTimeStr)) {
					//将同一天的数据相加
					dayUse =dayUse.add(new BigDecimal(dataMap.get("ThisUse")));
					
				}else{
					//当检测到天数改变时，拼接数据
					times.add(tempTimeStr);
					meterNum.add(dayUse+"");
					
					//并且更新tempTimeStr和dayUse
					dayUse = new BigDecimal(dataMap.get("ThisUse"));
					tempTimeStr = dataMap.get("ReadTime").substring(0, 10);
				}

			}
			res.add(times);
			res.add(meterNum);
		}
		return res;
	}
}




















